# string 字符串类型
import string

str_value = "Hello World~"
print(str_value)  # 输出完整的字符串
print(str_value[0])  # 输出字符串的第一个字符
print(str_value[2:5])  # 输出第 3 个 到第 4 个字符(因为字符串下标是从 0 开始;[:]是左闭右开区间)
print(str_value[2:])  # 输出第 3 个字符到结束
print(str_value[2:len(str_value)])  # 与上一个等价
print(str_value * 2)  # 输出两次字符串
print(str_value + 'python')  # 字符串拼接

print("==== 字符串转义字符 ====")
"""
\(在行尾时) : 表示续行符
\\ : 表示反斜杠
\' : 表示单引号
\" : 表示双引号
\a : 响铃
\b : 退格(Backspace)
\000 : 空
\n : 表示换行
\v : 表示纵向制表符
\t : 表示横向制表符
\r : 表示回车
\f : 表示换页
\0yy : 八进制数,yy表示字符;例如:\012 表示换行
\x0a : 十六进制数,0a表示字符;例如:\x0a
\other : 其他的字符以普通的格式输出
"""
print("\\")
print("\'")
print("\"")
print("\000")
print("\012")
print("\x0a")
print("\e")

print("==== 字符串运算 ====")
a = "Hello"
b = "Python"
print(a + b)  # 字符串拼接
print(a * 3)  # 字符串输出3次
print(a[1])  # 通过索引获取字符串中的某个字符
print(b[2:4])  # 字符串截取
print("t" in b)  # 成员运算符,如果字符在字符串中,则返回 True
print("o" not in a)  # 成员运算符,如果字符不在字符串中,则返回 True
print(r'\n')
print(R'\a')  # 原始字符串,没有转义
print("My name is %s" % ('张三'))  # 格式化字符,与 C 语言中的一样

print("==== 字符串格式化 ====")
print("%c" % ("a"))  # 格式化字符
print("%c" % 65)  # 格式化字符的 ASCII 码
print("%d" % 10)  # 格式化整数
print("%o" % 0o12)  # 格式化八进制数
print("%x" % 0xa)  # 格式化十六进制数
print("%f" % 3.14)  # 格式化浮点数
print("%e" % 3.1E2)  # 用科学计数法格式化浮点数

print("==== format() 格式化字符串 ====")
print("{} {}".format("Hello", "World"))  # 不指定位置,按默认顺序输出
print("{1} {0}".format("Hello", "World"))  # 设置指定位置
print("{1} {0} {1}".format("Hello", "World"))  # 设置指定位置

# 设置参数
print("网站名:{name},地址:{URL}".format(name="百度", URL="www.baidu.com"))
# 通过字典设置参数
site = {'name': '百度', "url": "www.baidu.com"}
print("网站名:{name},地址:{url}".format(**site))
# 通过列表索引设置参数
my_list = ['百度', 'www.baidu.com']
print("网站名:{0[0]},地址:{0[1]}".format(my_list))  # '0' 是因为后面只有一个列表,所以选定第一个.可以有多个列表,各个列表中选相应的值
my_list1 = ['搜狗', '百度']
my_list2 = ['www.baidu.com', 'www.sougou.com']
print("网站名:{0[1]},地址:{1[0]}".format(my_list1, my_list2))  # '0'/'1' 可以有多个列表,各个列表中选相应的值

print("==== format() 格式化数字 ====")
print("{:.2f}".format(3.1415926))  # 保留小数点后的两位数
print("{:+.2f}".format(3.1415926))  # 带符号保留小数点后的两位数
print("{:.0f}".format(2.7181))  # 不保留小数,且四舍五入
print("{:0>3d}".format(5))  # 左边补0,宽度为3
print("{:3>3d}".format(5))  # 左边补3,宽度为3
print("{:1<4d}".format(5))  # 右边补1,宽度为4
print("{:2<4d}".format(5))  # 右边补2,宽度为4
print("{:,}".format(12345))  # 以逗号分隔
print("{:.2%}".format(0.25))  # 百分比格式(25.00%)
print("{:.4%}".format(0.25))  # 百分比格式(25.0000%)
print("{:.2e}".format(1000000))  # 科学计数法表示
print("{:>10d}".format(5))  # 右对齐(默认:空格,宽度为10)
print("{:<10d}".format(5))  # 左对齐(默认:空格,宽度为10)
print("{:^10d}".format(5))  # 居中对齐(默认:空格,宽度为10)
print("{} 对应的位置是 {{0}}".format("run"))  # 使用大括号'{{}}'来转义大括号'{}'

print("==== Unicode ====")
print("Hello\u0020World~")  # \u0020 表示空格

print("==== 字符串内置函数的使用 ====")
str_value = "helloWorld"
print(str_value.capitalize())  # 将字符串的第一个字母变成大写,其他字母变成小写(字符串首字母大写)
print(str_value.center(20))  # 返回一个原字符串居中,并使用空格填充长度至20的新字符串
print(str_value.ljust(20))  # 字符串左对齐,并使用空格填充字符串至长度为 20
print(str_value.rjust(20))  # 字符串右对齐,并使用空格填充字符串至长度为 20
print(str_value.count('l'))  # 返回 'l'在字符串中出现的次数
print(str_value.count('l', 1, len(str_value)))  # 返回 'l'在字符串中出现的次数,可以指定范围
print(str_value.encode(encoding='UTF-8', errors='replace'))  # 以 encoding 指定的编码格式编码字符串,如果出错默认报一个 ValueError 的异常,除非 errors 指定的是 'ignore' 或 'replace'
print(str_value.endswith('ld'))  # 检查字符串是否以'ld'结尾,如果是则返回 True,否则返回 False
print(str_value.endswith('ld', 3, 6))  # 在范围内[3,6],检查字符串是否以'ld'结尾,如果是则返回 True,否则返回 False
print(str_value.find('llo'))  # 检查子串 'llo' 是否在str_value字符串中,如果在则返回子串在字符串中开始的索引,否则返回-1
print(str_value.find('llo', 5, 7))  # 在指定范围内检查子串是否在字符串中,如果在则返回子串在字符串中开始的索引,否则返回-1
print(str_value.rfind('or'))  # 查找子串,返回子串最后一次出现的位置(从右向左查询)返回其下标,如果没有则返回-1
print(str_value.rfind('or', 2, 5))  # 指定范围内从右向左查找子串
print(str_value.index('or'))  # 与 find() 一样,不同的是:如果子串不在字符串中则抛出异常
# print(str_value.index('ord'))  # 抛出异常:ValueError: substring not found
print(str_value.rindex('ll'))  # 与 rfind() 一样,不同的是:如果子串不在字符串中则抛出异常
# print(str_value.rindex('ll', 3, 7))  # 抛出异常:ValueError: substring not found
print(str_value.isalnum())  # 如果字符串所有字符都是字母或数字,并且至少有一个字符,则返回 True,否则返回 False
print('123'.isalnum())
print('abc123'.isalnum())
print('蟒蛇'.isalnum())
print('#'.isalnum())  # False
print(str_value.isdigit())  # 如果字符串只包含数字,则返回 True,否则返回 False
print('123'.isdigit())
print('abc123'.isdigit())
print(str_value.islower())  # 字符串中全是小写字符则返回 True,否则返回 False
print('abc def'.islower())
print(str_value.isupper())  # 如果字符串中全是大写字符则返回 True,否则返回 False
print('HELLO'.isupper())
print(str_value.isspace())  # 如果字符串中只是[\t\n\r\x0b\f](空格、制表符、换行符、回车、垂直制表符、换行符),则返回 True,否则返回 False
print(' '.isspace())
print('\t'.isspace())
print(str_value.istitle())  # 如果字符串中单词的首字母大写则返回 True,否则返回 False
print('Hello World'.istitle())
temp_str_value = 'PYF'
print(str_value.join(temp_str_value))  # 以字符串为分隔符,将 temp_str_value 中所有的元素合并为一个新的字符串
print(str_value.lower())  # 将字符串中所有的大写字符转换为小写字符
print(str_value.upper())  # 将字符串中的所有字符都转变为大写
print(str_value.lstrip('hel'))  # 删除字符串左边的指定字符集(删除的字符必须从左边第一个字符开始连续)
print('www.baidu.com'.lstrip('w.'))
print(max(str_value))  # 返回字符串中 ASCII 码值最大的字符
print(min(str_value))  # 返回字符串中 ASCII 码值最小的字符
print(str_value.partition('lo'))  # 字符串从左边开始查找子串'lo',以'lo'为基准将字符串分为三部分:'lo'左边/'lo'/'lo'右边;如果传入的子串在字符串中不存在,则会分割为:字符串/''/'',返回一个元组
print(str_value.rpartition('or')) # 字符串从右边开始查找子串'or',以'or'为基准将字符串分为三部分:'or'左边/'or'/'or'右边;如果传入的子串在字符串中不存在,则会分割为:''/''/字符串,返回一个元组
print(str_value.replace('he','py'))  # 将字符串中的'he'子串用'py'子串替换
print(str_value.rstrip('ld'))  # 删除字符串末尾的空格或指定的子串
print('www.baidu.com'.split('.'))  # 以指定子串进行分割,返回一个列表
print('hello\npython'.splitlines(keepends=False))  # 按照行('\r','\n')分割,返回一个列表,如果 keepends 为 False,则不包含换行符
print('hello\rpython'.splitlines(keepends=True))  # 按照行('\r','\n')分割,返回一个列表,如果 keepends 为 True,则包含换行符
print(str_value.startswith('he'))  # 检查字符串是否以'he'开头,如果是则返回 True,否则返回 False
print(str_value.startswith('he', 3, 5))  # 在指定范围内检查字符串是否以'he'开头,如果是则返回 True,否则返回 False
print(str_value.strip('hd'))  # 移除字符串头尾指定的字符,默认为空格
print(str_value.swapcase())  # 字符串中的字符大小写转换(大小变小写,小写变大写)
print("hello python".title())  # 字符串中每个单词的首字母大写其余小写
print(str_value.zfill(15))  # 返回长度为 15 的字符串,字符串右对齐,左侧补0
print(str_value.isdecimal())  # 检查字符串是否包含全是数字,如果是则返回 True,否则返回 False
print('1245'.isdecimal())  # 如果字符串中至少有一个字符且所有字符都是十进制字符则返回True，否则返回False。
test_str = 'Hello\tWorld!'
print(test_str.expandtabs(tabsize=10))  # 将字符串中的制表符(tab->\t)转换为空格,tab默认的空格数是8

"""
join() 函数: 可以在不修改别人源代码的基础上,进行增加字符
"""
# decode() 方法:Python3中没有这个方法,但是我们可以使用 bytes对象的 decode()方法来解码给定的 bytes对象,这个bytes对象可以有str.encode()编码返回
print(str_value.encode(encoding='utf-8'))
print(str_value.encode(encoding='gbk'))
print(str_value.encode(encoding='utf-8').decode(encoding='utf-8'))
print(str_value.encode(encoding='gbk').decode(encoding='gbk'))

print("==== 字符串的存储与保存 ====")
"""
python 字符串类型是str,在内存中以Unicode表示,一个字符对应若干个字节.
如果在网络上传输,或者保存到磁盘上,需要把str变为以字节为单位的bytes.
Python对 bytes 类型的数据用带 b 前缀的单引号或双引号表示.
"""
print('ABC'.encode('ascii'))
print('中文'.encode('utf-8'))

# 要把bytes变为str,需要用到decode()方法
print(b'ABC'.decode('ascii'))
print(b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8'))

# 计算 str 包含多少个字符
print(len('ABC'))
print(len('中文'))  # 一个中文占3个字节,一个英文占1个字节

print(len(b'ABC'))
print(len(b'\xe4\xb8\xad\xe6\x96\x87'))
print(len('中文'.encode('utf-8')))

print("==== maketrans() 函数,字符映射转换 ====")
"""
str.maketrans(intab,outtab)
intab:字符串中要替代的字符组成的字符串
outtab:相应的映射字符的字符串
两个字符串的长度必须相同,为一一对应的关系

str.translate(table) 
bytes.translate(table[,delete]) 
bytearray.translate(table[,delete]) 
translate(table)
功能:根据参数table给出的表(包含 256 个字符)转换字符串的字符,要过滤掉的字符放到 deletechars 参数中
table:翻译表,是通过 maketrans() 函数转换而来
deletechars:字符串中药过滤的字符列表
返回值:返回翻译后的字符串,若给出了 delete 参数,则将原来的 bytes 中的属于 delete 的字符删除,剩下的字符按照table中给出的映射进行映射
"""
intab = 'aeiou'
outtab = '12345'
trantab = str.maketrans(intab, outtab)
print(trantab)

str_tab = "this is string example...wow!!!"
# 根据 trantab 转换表转换字符串的字符
print(str_tab.translate(trantab))  # 将 str_tab 中的 aeiou 转换为 12345

# 转换为大写,并删除字母 o
bytes_tabtrans = bytes.maketrans(b'abcdefghijklmnopqrstuvwxyz', b'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
print(b'lenovo'.translate(bytes_tabtrans, b'o'))

print("==== 字符串格式化 ====")
for x in range(1,11):
    print(str(x).rjust(2),str(x*x).rjust(3),end='')
    print(str(x*x*x).rjust(4))

for x in range(1,11):
    print('{0:2d}{1:3d}{2:4d}'.format(x,x*x,x*x*x))

for x in range(1,11):
    print("%2d %3d %4d" % (x, x*x, x*x*x))


print("==== 美化表格 ====")
table = {'Google':1,'Baidu':2,'Taobao':3,'Tencent':4}
for name,number in table.items():
    print('{:10}==>{:10d}'.format(name, number))


# input() 函数输入得到的数据都是str类型
# 可以通过数据类型转换将字符串转换为数字
a = float(input("输入数字:"))
b = float(input("输入数字:"))
print(a + b)
